package com.imooc.user.service.impl;

import com.imooc.enums.Sex;
import com.imooc.enums.UserStatus;
import com.imooc.exception.GraceException;
import com.imooc.grace.result.ResponseStatusEnum;
import com.imooc.pojo.AppUser;
import com.imooc.pojo.bo.UpdateUserInfoBO;
import com.imooc.pojo.vo.PublisherVO;
import com.imooc.user.mapper.AppUserMapper;
import com.imooc.user.mapper.AppUserMapperCustom;
import com.imooc.user.service.UserService;
import com.imooc.utils.DateUtil;
import com.imooc.utils.DesensitizationUtil;
import com.imooc.utils.JsonUtils;
import com.imooc.utils.RedisOperator;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserServiceImpl implements UserService {

    /**
     * 一些默认图片
     */
    private static final String USER_FACE0 = "http://122.152.205.72:88/group1/M00/00/05/CpoxxFw_8_qAIlFXAAAcIhVPdSg994.png";
    private static final String USER_FACE1 = "http://122.152.205.72:88/group1/M00/00/05/CpoxxF6ZUySASMbOAABBAXhjY0Y649.png";
    private static final String USER_FACE2 = "http://122.152.205.72:88/group1/M00/00/05/CpoxxF6ZUx6ANoEMAABTntpyjOo395.png";

    /**
     * 用户信息的key
     */
    public static final String REDIS_USER_INFO = "redis_user_info";

    @Autowired
    public Sid sid;

    @Autowired
    public RedisOperator redis;

    @Autowired
    public AppUserMapper appUserMapper;

    @Autowired
    public AppUserMapperCustom appUserMapperCustom;


    /**
     * 判断用户是否存在, 如果存在返回user信息
     */
    @Override
    public AppUser queryMobileIsExist(String mobile) {
        Example userExample = new Example(AppUser.class);
        Example.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andEqualTo("mobile", mobile);
        return appUserMapper.selectOneByExample(userExample);
    }

    /**
     * 创建用户, 新增用户记录到数据库
     */
    @Override
    @Transactional
    public AppUser createUser(String mobile) {
        String userId = sid.nextShort();
        AppUser user = new AppUser();
        user.setId(userId);
        user.setMobile(mobile);
        user.setNickname("用户：" + DesensitizationUtil.commonDisplay(mobile));
        user.setFace(USER_FACE0);   // 创建用户使用默认的图片
        user.setBirthday(DateUtil.stringToDate("1900-01-01"));
        user.setSex(Sex.secret.type);
        user.setActiveStatus(UserStatus.INACTIVE.type); // 账号状态默认未激活
        user.setTotalIncome(0);
        user.setCreatedTime(new Date());
        user.setUpdatedTime(new Date());
        appUserMapper.insert(user);
        return user;
    }

    /**
     * 根据用户主键id查询用户信息
     */
    @Override
    public AppUser getUser(String userId) {
        return this.appUserMapper.selectByPrimaryKey(userId);
    }

    /**
     * 用户修改信息, 完善资料, 并且激活
     */
    @Override
    public void updateUserInfo(UpdateUserInfoBO updateUserInfoBO) {
        // 保证双写一致, 先删除 redis 中的数据, 后更新数据库
        this.redis.del(REDIS_USER_INFO + ":" + updateUserInfoBO.getId());

        // 初始化用户信息对象
        AppUser userInfo = new AppUser();
        BeanUtils.copyProperties(updateUserInfoBO.getId(), userInfo);
        userInfo.setUpdatedTime(new Date());
        userInfo.setActiveStatus(UserStatus.ACTIVE.type);   // 用户的状态修改为激活状态

        // 修改数据库的用户信息
        int result = appUserMapper.updateByPrimaryKeySelective(userInfo);
        if (result != 1) {
            GraceException.display(ResponseStatusEnum.USER_UPDATE_ERROR);
        }

        // 再次查询用户的最新信息, 放入 redis 中
        AppUser user = getUser(updateUserInfoBO.getId());
        this.redis.set(REDIS_USER_INFO + ":" + updateUserInfoBO.getId(), JsonUtils.objectToJson(user));

        // 缓存双删策略, 休眠 100ms, 再次删除缓存信息, 等待后续的查询操作再将信息的用户信息同步到缓存中
        try {
            Thread.sleep(100);
            redis.del(REDIS_USER_INFO + ":" + updateUserInfoBO.getId());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<PublisherVO> getUserList(List<String> userIdList) {
        Map<String, Object> map = new HashMap<>();
        map.put("userIdList", userIdList);
        return appUserMapperCustom.getUserList(map);
    }
}
